/**
 * 带缓存功能的Cesium ImageryProvider
 * 继承自UrlTemplateImageryProvider，添加本地缓存支持
 */

import * as Cesium from "cesium";
import mapTileCache from "./mapTileCache.js";

class CachedImageryProvider extends Cesium.UrlTemplateImageryProvider {
  constructor(options) {
    super(options);
    this.enableCache = options.enableCache !== false; // 默认启用缓存
    this.cacheInstance = mapTileCache;
  }

  /**
   * 重写requestImage方法，添加缓存逻辑
   */
  requestImage(x, y, level, request) {
    if (!this.enableCache) {
      // 如果禁用缓存，直接调用父类方法
      return super.requestImage(x, y, level, request);
    }

    // 构建瓦片URL - 手动构建URL
    const url = this.buildTileUrl(x, y, level);

    return this.requestImageWithCache(url, x, y, level, request);
  }

  /**
   * 构建瓦片URL
   */
  buildTileUrl(x, y, level) {
    // 高德地图URL模板
    const template =
      "https://webst{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}";

    // 选择子域名
    const subdomains = ["01", "02", "03", "04"];
    const subdomain = subdomains[(x + y + level) % subdomains.length];

    // 替换模板变量
    return template
      .replace("{s}", subdomain)
      .replace("{x}", x.toString())
      .replace("{y}", y.toString())
      .replace("{z}", level.toString());
  }

  /**
   * 带缓存的图片请求方法
   */
  async requestImageWithCache(url, x, y, level, request) {
    try {
      // 首先尝试从缓存获取
      const cachedData = await this.cacheInstance.getTile(url);

      if (cachedData) {
        // 缓存命中，创建图片对象
        return this.createImageFromCachedData(cachedData);
      }

      // 缓存未命中，从网络加载
      return this.loadImageFromNetwork(url, request);
    } catch (error) {
      console.error("Error in requestImageWithCache:", error);
      // 发生错误时，尝试从网络加载
      return this.loadImageFromNetwork(url, request);
    }
  }

  /**
   * 从网络加载图片并缓存
   */
  async loadImageFromNetwork(url, request) {
    try {
      // 使用fetch加载图片
      const response = await fetch(url, {
        signal: request?.signal,
        headers: {
          Accept: "image/*",
        },
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      // 获取图片数据
      const arrayBuffer = await response.arrayBuffer();

      // 异步缓存数据（不阻塞图片显示）
      this.cacheInstance.cacheTile(url, arrayBuffer).catch((error) => {
        console.warn("Failed to cache tile:", error);
      });

      // 创建图片对象
      return this.createImageFromArrayBuffer(arrayBuffer);
    } catch (error) {
      console.error("Failed to load image from network:", error);

      // 如果网络请求失败，返回一个拒绝的Promise
      // Cesium会处理这个错误并可能显示占位符
      throw error;
    }
  }

  /**
   * 从缓存数据创建图片
   */
  createImageFromCachedData(cachedData) {
    if (cachedData instanceof ArrayBuffer) {
      return this.createImageFromArrayBuffer(cachedData);
    } else if (typeof cachedData === "string") {
      // 如果是base64数据
      return this.createImageFromDataUrl(cachedData);
    } else {
      throw new Error("Unsupported cached data format");
    }
  }

  /**
   * 从ArrayBuffer创建图片
   */
  createImageFromArrayBuffer(arrayBuffer) {
    return new Promise((resolve, reject) => {
      const blob = new Blob([arrayBuffer]);
      const url = URL.createObjectURL(blob);

      const image = new Image();

      image.onload = () => {
        URL.revokeObjectURL(url); // 清理对象URL
        resolve(image);
      };

      image.onerror = () => {
        URL.revokeObjectURL(url); // 清理对象URL
        reject(new Error("Failed to create image from cached data"));
      };

      image.src = url;
    });
  }

  /**
   * 从Data URL创建图片
   */
  createImageFromDataUrl(dataUrl) {
    return new Promise((resolve, reject) => {
      const image = new Image();

      image.onload = () => {
        resolve(image);
      };

      image.onerror = () => {
        reject(new Error("Failed to create image from data URL"));
      };

      image.src = dataUrl;
    });
  }

  /**
   * 获取缓存统计信息
   */
  async getCacheStats() {
    return await this.cacheInstance.getCacheStats();
  }

  /**
   * 清空缓存
   */
  async clearCache() {
    return await this.cacheInstance.clearAllCache();
  }

  /**
   * 启用/禁用缓存
   */
  setEnableCache(enable) {
    this.enableCache = enable;
  }

  /**
   * 检查是否启用缓存
   */
  isCacheEnabled() {
    return this.enableCache;
  }
}

export default CachedImageryProvider;
